/**
 * 
 */
package ru.olympus.antonyhands.ao.server;

import java.util.Comparator;
import java.util.List;

import ru.olympus.antonyhands.ao.client.AOHelperService;
import ru.olympus.antonyhands.ao.client.AOHelperServiceAsync;
import ru.olympus.antonyhands.ao.client.widgets.TreeTable.TreeTableDataSource;
import ru.olympus.antonyhands.ao.server.db.AOData;
import ru.olympus.antonyhands.ao.server.item.CraftInfo;
import ru.olympus.antonyhands.ao.server.item.CraftSkill;
import ru.olympus.antonyhands.ao.server.item.Item;
import ru.olympus.antonyhands.ao.server.item.ItemCategory;
import ru.olympus.antonyhands.ao.server.item.ItemQuantityPair;
import ru.olympus.antonyhands.ao.server.item.util.ItemBaseToStringPairTransformer;
import ru.olympus.antonyhands.ao.server.item.util.ItemByUniversalParentFilter;
import ru.olympus.antonyhands.ao.server.item.util.ItemOrderComparator;
import ru.olympus.antonyhands.ao.server.item.util.ItemToStringPairTransformer;
import ru.olympus.antonyhands.ao.server.item.util.StringPairToItemQuantityPairTransformer;
import ru.olympus.antonyhands.ao.server.util.GoogleIterable;
import ru.olympus.antonyhands.ao.server.util.TreeTableDSHelper;
import ru.olympus.antonyhands.ao.shared.item.EItemParentType;
import ru.olympus.antonyhands.ao.shared.item.ItemDTO;
import ru.olympus.antonyhands.ao.shared.item.ItemMarketPriceDTO;
import ru.olympus.antonyhands.ao.shared.item.EItemsViewType;
import ru.olympus.antonyhands.ao.shared.util.StringPair;
import ru.olympus.antonyhands.ao.shared.util.StringUtilities;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * @author AntonyHands
 * @since 14.02.2012
 */
public class AOHelperServiceImpl extends RemoteServiceServlet implements AOHelperService
{

    private static final long serialVersionUID = 6129760876677512414L;

    public AOHelperServiceImpl()
    {
        
    }

    @Override
    public String addItemBase(String itemType, String code, String title)
    {
        boolean result;
        if (AOHelperServiceAsync.ITEM_CATEGORY.equals(itemType))
            result = AOData.getInstance().addItemCategory(new ItemCategory(code, title));
        else if (AOHelperServiceAsync.CRAFT_SKILL.equals(itemType))
            result = AOData.getInstance().addCraftSkill(new CraftSkill(code, title));
        else
            return "Неизвестный тип добавляемого объекта";
        if (result)
            return "";
        else
            return "Категория с таким кодом или наименованием уже существует";
    }

    @Override
    public String saveData()
    {
        try
        {
            AOData.getInstance().doSave();
            return "";
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return "Произошла ошибка при сохранении данных";
        }
    }

    @Override
    public List<StringPair> listItemCategories()
    {
        return GoogleIterable
                .with(AOData.getInstance().listItemCategories())
                .transform(new ItemBaseToStringPairTransformer())
                .toArrayList();
    }

    @Override
    public List<StringPair> listCraftSkills()
    {
        return GoogleIterable
                .with(AOData.getInstance().listCraftSkills())
                .transform(new ItemBaseToStringPairTransformer())
                .toArrayList();
    }

    @Override
    public List<StringPair> listItems(EItemParentType parentType, String parentCode, EItemsViewType viewType)
    {
        return GoogleIterable
            .with(AOData.getInstance().listItems())
            .filter(new ItemByUniversalParentFilter(parentType, parentCode))
            .sort(new ItemOrderComparator(viewType))
            .transform(new ItemToStringPairTransformer(viewType))
            .toArrayList();
    }

    @Override
    public String addItem(String code, String title, String categoryCode, String fixedPrice, String craftSkillCode, String craftLevel, String workload, String craftQuantity, List<StringPair> resources)
    {
        ItemCategory cat = AOData.getInstance().getItemCategoryByCode(categoryCode);
        if (cat == null)
            return "Ошибка при определении типа предмета";
        Item item = new Item(code, title, cat);
        Long fixedPriceLong = StringUtilities.stringToLong(fixedPrice);
        if (AOData.getInstance().addItem(item))
        {
            item.setFixedPrice(fixedPriceLong);
            if (!StringUtilities.isEmpty(craftSkillCode))
            {
                Long lCraftLevel = StringUtilities.stringToLong(craftLevel);
                Long lWorkload = StringUtilities.stringToLong(workload);
                Long lCraftQuantity = StringUtilities.stringToLong(craftQuantity);
                CraftSkill skill = AOData.getInstance().getCraftSkillByCode(craftSkillCode);
                CraftInfo ci = new CraftInfo(skill, lCraftLevel, lWorkload, 
                        new ItemQuantityPair(item, lCraftQuantity), 
                        GoogleIterable.with(resources).transform(new StringPairToItemQuantityPairTransformer()).toArrayList());
                AOData.getInstance().addCraftInfo(ci);
            }
            return "";
        }
        else
            return "Предмет с таким кодом или наименованием уже существует";
    }

    @Override
    public ItemDTO getItemDTO(String itemCode)
    {
        Item _item = AOData.getInstance().getItemByCode(itemCode);
        return _item.toDTO();
    }

	@Override
	public String saveMarketPrice(String itemCode, String marketPrice) {
		Item _item = AOData.getInstance().getItemByCode(itemCode);
		_item.setMarketPrice(StringUtilities.stringToLong(marketPrice));
		return null;
	}

	@Override
	public List<ItemMarketPriceDTO> listMarketPricesHierarchyList(
			String itemCode) {
		return GoogleIterable
			.with(AOData.getInstance().getItemByCode(itemCode).getMarketPriceDTOForHierarchy().values())
			// сортируем по названию
			.sort(new Comparator<ItemMarketPriceDTO>() {
				@Override
				public int compare(ItemMarketPriceDTO o1, ItemMarketPriceDTO o2) {
					return o1.getItem().getValue().compareTo(o2.getItem().getValue());
				}
			})
			.toArrayList();
	}

	@Override
	public String updateItemsMarketPrices(List<StringPair> itemPrices) {
		for (StringPair sp : itemPrices)
		{
			AOData.getInstance().getItemByCode(sp.getKey()).setMarketPrice(StringUtilities.stringToLong(sp.getValue()));
		}
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public TreeTableDataSource getItemCraftDS(String itemCode) {
		TreeTableDataSource ds = new TreeTableDataSource();
		Item item = AOData.getInstance().getItemByCode(itemCode);
		ds.setHeadRow(TreeTableDSHelper.createHeader());
		ds.addRow(TreeTableDSHelper.createRowForItem(item, 0, new Long(1)));
		return ds;
	}

}
